package com.example.mybatisplus.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.plugins.pagination.PageHelper;
import com.example.mybatisplus.entity.User;
import com.example.mybatisplus.entity.enums.AgeEnum;
import com.example.mybatisplus.entity.enums.PhoneEnum;
import com.example.mybatisplus.service.IUserService;
import com.example.mybatisplus.util.SQLFilter;


/**
 * 代码生成器，参考源码测试用例：
 * <p>
 * /mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/generator/MysqlGenerator.java
 */
@RestController
@RequestMapping("/user")
public class UserServiceController {

    @Autowired
    private IUserService userService;
    

    /**
     * 分页 PAGE
     * 
     * 在serviceImpl实现类中可以调用super.XXX()方法来调用service提供的方法，也可以调用mapper
     * 中自己写的
     * 
     * 
     */
    @GetMapping("/test")
    public Page<User> test() {
        return userService.query();
    }

  
    /**
     * 增删改查 CRUD
     */
    @GetMapping("/test2")
    public User test2() {
        System.err.println("删除一条数据：" + userService.deleteById(1L));
        System.err.println("deleteAll：" + userService.deleteAll());
        System.err.println("插入一条数据：" + userService.insert(new User(1L, "张三", AgeEnum.TWO, 1)));
        User user = new User("张三", AgeEnum.TWO, 1);
        boolean result = userService.insert(user);
        // 自动回写的ID
        Long id = user.getId();
        System.err.println("插入一条数据：" + result + ", 插入信息：" + user.toString());
        System.err.println("查询：" + userService.selectById(id).toString());
        System.err.println("更新一条数据：" + userService.updateById(new User(1L, "三毛", AgeEnum.ONE, 1)));
        for (int i = 0; i < 5; ++i) {
            userService.insert(new User(Long.valueOf(100 + i), "张三" + i, AgeEnum.ONE, 1));
        }
        Page<User> userListPage = userService.selectPage(new Page<User>(1, 5), new EntityWrapper<User>(new User()));
        System.err.println("total=" + userListPage.getTotal() + ", current list size=" + userListPage.getRecords().size());
        return userService.selectById(1L);
    }
    
    
   /**
    * 插入
    * @return
    */
    @GetMapping("/add")
    public User add() {
    	User user = new User("李四", AgeEnum.TWO, 1);
        boolean result = userService.insert(user);
     // 自动回写的ID
        Long id = user.getId();
        System.out.println("插入的ID:"+id);
        System.err.println("插入一条数据：" + result + ", 插入信息：" + user.toString());
        return user;
    }
    
    /**
     * 批量插入
     * @return
     */
    
    @GetMapping("/addList")
    public User addUserList() {
    	User user = new User("zhuzhu", AgeEnum.TWO, 1);
    	User user1 = new User("shahsa", AgeEnum.TWO, 1);
    	
    	List<User> list = new ArrayList<User>();
    	list.add(user1);
    	list.add(user);
        userService.insertBatch(list);
        
        List<Long> idList  = list.stream().map(u->u.getId()).collect(Collectors.toList());
        
        System.out.println("插入的ID:"+idList.size());
        return user;
    }

    
    
    @GetMapping("/update")
    public String updateUser() {
    	
    	User user = new User(1L, "AAAA", AgeEnum.ONE, 1);
    	User user1 = new User(2L, "BBBB", AgeEnum.ONE, 1);
    	//根据id更新
    	//userService.updateById(user);
    	
    	//批量更新
//    	List<User> list = new ArrayList<User>();
//    	list.add(user1);
//    	list.add(user);
//    	userService.updateBatchById(list,1);
    	
    	//按条件更新 name等于王五的都会更新
    	User user3 = new User("DDDD", AgeEnum.ONE, 1);
    	userService.update(user3, new EntityWrapper<User>().eq("name", "王五"));
    	
    	return "success";
    }
    
    
    @GetMapping("/delete")
    public String delete() {
    	//根据id删除
    	//userService.deleteById(1L);
    	
    	//根据条件删除
    	//userService.delete(new EntityWrapper<User>().eq("name", "王五"));
    	
    	//批量删除
    	
    	List<Long> idList = new ArrayList<Long>();
    	
    	idList.add(1012265671028301825L);
    	idList.add(1012284929342857217L);
    	
    	userService.deleteBatchIds(idList);
    	//删除所有
    	//userService.deleteAll();
    	
    	//以map作为条件删除
    	Map<String,Object> map = new HashMap<String,Object>();
    	map.put("name", "李四");
    	userService.deleteByMap(map);
    	
    	//逻辑删除
    	//若在test_type上加上@TableLogic 注解，并在配置文件中配置，则删除为逻辑删除，不是真删
    	
    	return "删除成功";
    }
    
    /**
     * 查询
     */
    
   
    
    @GetMapping("/select")
    public String select() {
    	//根据id查询
    	User user =  userService.selectById(1L);
    	
    	System.out.println(user.toString());
    	 
    	//根据id集合查询
    	List<Long> idList = new ArrayList<Long>();
    	
    	idList.add(1012265671028301825L);
    	idList.add(1012284929342857217L);
    	List<User> list = userService.selectBatchIds(idList);
    	
    	//计数		
    	int count = userService.selectCount(new EntityWrapper<User>().eq("name", "雷锋"));
    	//根据条件查询
    	List<User> userList = userService.selectList(new EntityWrapper<User>().eq("name", "雷锋"));
    	
    	//自定义sql查询
    	//userService.selectListBySQL();
    	
    	//map作为条件查询
    	Map<String,Object> map = new HashMap<String,Object>();
    	map.put("name", "李四");
    	List<User> userMap = userService.selectByMap(map);
    	
    	Map<String,Object> mapList = userService.selectMap(new EntityWrapper<User>().eq("name", "雷锋"));
    	
    	List<Map<String,Object>> map1 =  userService.selectMaps(new EntityWrapper<User>().eq("name", "雷锋"));
    	
    	
    	Page<Map<String, Object>> pageMap = userService.selectMapsPage(new Page<User>(0, 12), new EntityWrapper<User>().eq("name", "雷锋"));
    	
    	
    	
    	return "查询成功";
    }
    
    /**
     * 插入 OR 修改
     */
    @GetMapping("/test3")
    public User test3() {
        User user = new User(1L, "王五", AgeEnum.ONE, 1);
        user.setPhone(PhoneEnum.CT);
        System.out.println("插入前：" + user.toString());
        userService.insertOrUpdate(user);
        user = userService.selectById(1L);
        System.out.println("更新后：" + user.toString());
        return user;
    }


    /**
     * 测试实体注解注入条件 LIKE 查询
     */
    @GetMapping("/like")
    public Object like() {
        JSONObject result = new JSONObject();
        User user = new User();
        user.setName("三");
        result.put("result", userService.selectList(new EntityWrapper<User>(user)));
        return result;
    }

    

    @GetMapping("/selectsql")
    public Object getUserBySql() {
        JSONObject result = new JSONObject();
        result.put("records", userService.selectListBySQL());
        return result;
    }

    /**
     * 7、分页 size 一页显示数量  current 当前页码
     * 方式一：http://localhost:8080/user/page?size=1&current=1<br>
     * 方式二：http://localhost:8080/user/pagehelper?size=1&current=1<br>
     */

    // 参数模式分页
    @GetMapping("/page")
    public Object page(Page page) {
        return userService.selectPage(page);
    }

    // ThreadLocal 模式分页
    @GetMapping("/pagehelper")
    public Object pagehelper(Page page) {
        PageHelper.setPagination(page);
        page.setRecords(userService.selectList(null));
        page.setTotal(PageHelper.freeTotal());//获取总数并释放资源 也可以 PageHelper.getTotal()
        return page;
    }


    /**
     * 测试事物
     * http://localhost:8080/user/test_transactional<br>
     * 访问如下并未发现插入数据说明事物可靠！！<br>
     * http://localhost:8080/user/test<br>
     * <br>
     * 启动  Application 加上 @EnableTransactionManagement 注解其实可无默认貌似就开启了<br>
     * 需要事物的方法加上 @Transactional 必须的哦！！
     */
    @Transactional
    @GetMapping("/test_transactional")
    public void testTransactional() {
        userService.insert(new User(1000L, "测试事物", AgeEnum.ONE, 3));
        System.out.println(" 这里手动抛出异常，自动回滚数据");
        throw new RuntimeException();
    }
    
    @GetMapping("/testttt")
    public Page<User> selectAllaa(){

    	EntityWrapper<User> ew = new EntityWrapper<User>();
    	
    	//true和false会决定是否加上这个查询语句
    	//ew.like(false, "name", "三毛", SqlLike.DEFAULT);
    	
    	//执行exists语句
    	//ew.exists(true, "select test_id from user where test_id = 6");
    	
    	//addFilter
    	//ew.addFilter(" name like  {0} and test_id = {1} ", "%三毛%","1");
    	
    	//ew.addFilterIfNeed(false," name like  {0} and test_id = {1} ", "%三毛%","1");
    	//进行模糊查询时经常出现sql注入问题，使用这个工具类解决
    	ew.addFilterIfNeed(true,"name  like "+SQLFilter.EscpseSql(""));

    	
    	
    	//自定义SQL字段分组查询并过滤
    	//ew.setSqlSelect("test_id,name").groupBy("test_id,name").having("test_id={0}",1);

    	
    	//map作为条件查询
    	//FROM user WHERE (name = ? AND test_type = ?)
//    	Map<String,Object> map = new HashMap<String,Object>();
//    	map.put("test_type", "1");
//    	map.put("name", "三毛");
//    	ew.allEq(true, map);
    	
    	
    	//多条件查询  andNew后面的条件在括号外面
//    	ew.where("name = '三毛' ").where(true, "test_id = {0}", "1").and("age = {0} and test_type = {1}", 2,1)
//    	.andNew("role = {0}", 1).orNew("phone like {0}","%10086%");
    	
    	

    	
    	
    	 Page<User> page = userService.selectPage(new Page<User>(0,20),
    			 ew); 
    	 
    	 return page;
    }   
    
    public static void main(String[] args) {
    	StringBuffer sql = new StringBuffer("select key_sn,remark,create_date from tb_selogon_key where 1=1 ");

    	String keyword = "___";
            sql.append(" and like '%\\" + keyword + "%'" +"escape '\\'");

            String str  = "'%\\" + keyword + "%'"+"escape '\\'";
            System.out.println(str);

	}
}
